proc eval_exec_cmd {cmd} {
	global info
        set result [catch {eval exec $cmd} output]
        if {$result==0} {
                log_info $info "Run $cmd successfully. output: $output " 2
		return 1
        } else {
                log_info $info "Failed to run $cmd. error: $output" 2
		return 0
        }
}
proc get_value {widget title_str} {
	global commit_co_msg
	set content [$widget get 1.0 end]
	append title_str $content
	set commit_co_msg $title_str
}
proc input_co_msg {} {
	global info operator commit_co_msg
	set w .input_co_msg
	catch {destroy $w}
	toplevel $w
	wm title $w "Input commit record message"
	wm iconname $w "iconname?"
	positionWindow $w
	set co_time [clock format [clock second] -format "%b_%d_%Y"]
	set co_msg_title "Operator: $operator                                        Date: $co_time"
        set co_msg_content "Title:
Description:



	"
	label $w.title -text "$co_msg_title"
	pack $w.title -side top -anchor w
	set msg_txt [text $w.txt -yscrollcommand "$w.sb set"]
	scrollbar $w.sb -orient vertical -command "$msg_txt yview"
	pack $msg_txt -side left
	pack $w.sb -side left -fill y
	$msg_txt insert end $co_msg_content
	frame $w.command
	button $w.command.confirm -text "Confirm" -width 15 -command [list get_value $msg_txt $co_msg_title]
	button $w.command.cancel -text "Cancel" -width 15 -command [list set commit_co_msg "Cancel commiting"] 
	pack $w.command -side right  -fill x -pady 2m
	pack $w.command.confirm $w.command.cancel -side top -expand 1
	vwait commit_co_msg
	catch {destroy $w}
	return $commit_co_msg
}	
proc database_setup {} {
	global info
	log_info $info "module is building" 2
}
proc database_backup_structure {} {
	global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info
	set time [clock format [clock second] -format "%H_%M_%b%d_%Y"]
	set backup_cmd "/usr/bin/mysqldump $DB_NAME -h $DB_SERVER -u $DB_USER --password=$DB_PASS -c -d >cfg/database_structure.sql"
        catch {eval exec $backup_cmd} result
        if {$result==""} {
                log_info $info "Backup database structure successfully. " 2
        } else {
                log_info $info "Failed to backup database structure. error: $result" 2
        }
}

proc database_backup_data {} {
        global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info
        set time [clock format [clock second] -format "%H_%M_%b%d_%Y"]
        set backup_cmd "/usr/bin/mysqldump $DB_NAME -h $DB_SERVER -u $DB_USER --password=$DB_PASS -c -t >data/db_dataonly_$time.sql"
        catch {eval exec $backup_cmd} result
        if {$result==""} {
                log_info $info "Backup database data successfully. " 2
		return "db_dataonly_$time.sql"
        } else {
                log_info $info "Failed to backup database data. error: $result" 2
		return 0
        }
}
proc database_backup {} {
        global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info TB_LIST
        set time [clock format [clock second] -format "%H_%M_%b%d_%Y"]
        set backup_cmd "/usr/bin/mysqldump $DB_NAME -h $DB_SERVER -u $DB_USER --password=$DB_PASS -c >data/db_$time.sql"
	eval_exec_cmd $backup_cmd
}
proc export_level1_to_file {} {
        global SCRIPT_DIR info TREE_TB DB_NAME ENV_REPO_DIR
        #export all first-level env to env_file
        #search first-level in tree table
        set sql_qur "SELECT name from $TREE_TB where parentid='0' ORDER BY name "
        set sky_response [mysql_pack $sql_qur $DB_NAME ]
        set parent_line [lindex $sky_response 0]
        set sql_ret_str [lindex $sky_response 1]
        set k 0

        if {$parent_line > "0"} {
                log_info $info "Found $parent_line package records in DB!\n" 2
                catch {unset env}
                for {set i 1} {$i <= $parent_line} {incr i +1} {
                        set env($i) [lindex $sql_ret_str $k]
                        incr k +1
                }
                for {set i 1} {$i <= $parent_line} {incr i +1} {
                        set cur_env $env($i)
                        eval cd $SCRIPT_DIR
                        set env_name $ENV_REPO_DIR
                        append env_name [string map {/ _ . _} $cur_env]
                        append env_name ".env"
                        log_info $info "exporting env:$cur_env to file $env_name;" 2
                        export_env_file $env_name $cur_env
                }
        }
}
proc database_commit {} {
        global SCRIPT_DIR info TREE_TB db_handle ENV_REPO_DIR
	#export all level 1 env data to file
	export_level1_to_file
        #start to commit it to repository
        set commit_msg [input_co_msg]
        if {$commit_msg!="Cancel commiting"} {
                set cmd "svn commit $ENV_REPO_DIR -m \"$commit_msg\""
                if {[eval_exec_cmd $cmd]==0} {
                        log_info $info "Commit file failed, need check it manually" 2
                        set fail_commit 1
                } else {
                        log_info $info "Commit database succeeded!" 2
                        log_info $info "###If output list some conflict file, you have to fix it and then commit it manually!###" 2
                        set fail_commit 0
                }
        } else {
                log_info $info "Cancel to commit data" 2
        }
}
proc database_update_date {} {
        global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info TB_LIST ENV_REPO_DIR
	#We should dump local database data to file firstly,then update from svn. otherwise Changes in local database will lost  
	#export all level 1 env data to file
	export_level1_to_file
	#Now we can update data from central database
	set cmd "svn update $ENV_REPO_DIR"
	if {[eval_exec_cmd $cmd]==0} {
       		log_info $info "Update db file failed, need check it manually" 2
		return 0
        } else {
        	log_info $info "Update db file succeeded! Start to restore to local DB. ###If output list some conflict files, you have to fix it and then commit it manually!###" 2
        }
	#Now we should restore all changed file to local db

}

proc database_restore {} {
        global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info
	set types {
		{{Sql Files}  {.sql} }
		{{All Files}  *      }
	}
	set restore_file_name [tk_getOpenFile -filetypes $types]
        log_info $info "restore file name: $restore_file_name." 2
        set backup_cmd "mysql -h $DB_SERVER -u $DB_USER --password=$DB_PASS $DB_NAME <$restore_file_name"
        catch {eval exec $backup_cmd} result
	if {$result==""} {
	        log_info $info "Restore data to database successfully. " 2
	} else {
		log_info $info "Failed to restore data to database. error: $result" 2
	}
}
proc database_upgrade_structure {} {
        global DB_NAME DB_SERVER DB_USER DB_PASS SCRIPT_DIR info
	if {[set datafile_name [database_backup_data]] != 0} {
		#upgrade structure
                set backup_cmd "mysql -h $DB_SERVER -u $DB_USER --password=$DB_PASS $DB_NAME <cfg/database_structure.sql"
                catch {eval exec $backup_cmd} result
                if {$result==""} {
                        log_info $info "Upgrade database structure successfully.Now it's time to restore data " 2
                } else {
                        log_info $info "Failed to Upgrade database structure. error: $result" 2
                }
		#restore data
                set restore_data_cmd "mysql -h $DB_SERVER -u $DB_USER --password=$DB_PASS $DB_NAME <data/$datafile_name"
                catch {eval exec $restore_data_cmd} result
                if {$result==""} {
                        log_info $info "Restore data successfully." 2
                } else {
                        log_info $info "Failed to restore data. error: $result" 2
                }
	} else {
                log_info $info "Failed to Backup data, ignore to upgrade structure" 2
	}
}
proc database_schedule_backup {} {
	global info
	log_info $info "module is building" 2
}

